<?php

namespace Easy\Entity;

use Easy\DbContainer;
use Easy\Exception\LogicError;

class Hook
{
    const SQL_INSERT = 1;
    const SQL_FETCH  = 2;
    const SQL_DELETE = 3;

    private static $_entity = [];

    public static function setModel($cls, $model = self::SQL_FETCH)
    {
        if (!$cls->getID()) {
            return;
        }
        $hookDTO = self::getEntityHookDTO($cls);
        $hookDTO->setModel($model);

        return;
    }

    public static function cleanModel($cls)
    {
        $hookDTO = self::getEntityHookDTO($cls);
        $hookDTO->setModel(null);

        return;
    }

    private static function getEntityHookDTO($cls)
    {
        $className = get_class($cls);
        if (isset(self::$_entity[$className][$cls->getID()])) {

            return self::$_entity[$className][$cls->getID()];
        } else {
            $hookDTO                                  = new HookDTO();
            $hookDTO->class                           = $cls;
            self::$_entity[$className][$cls->getID()] = $hookDTO;

            return $hookDTO;
        }
    }

    public static function clsSet($cls, $name, $value)
    {
        $hookDTO = self::getEntityHookDTO($cls);
        $hookDTO->setValue($name, $value);
    }

    public static function clsGet($cls, $name)
    {
        $hookDTO = self::getEntityHookDTO($cls);

        return $hookDTO->getValue($name);
    }

    public static function debugClsAttr()
    {
        return self::$_entity;
    }

    public static function commit()
    {
        try {
            foreach (self::$_entity as $k => $v) {
                foreach ($v as $ek => $hookDTO) {
                    $entity         = $hookDTO->class;
                    $tableName      = $entity->getTable();
                    $dbInstanceName = $entity->getDbInstance();
                    $dbInstance     = DbContainer::get($dbInstanceName);
                    DbContainer::startTrans($dbInstanceName);
                    $hookDTO = self::getEntityHookDTO($entity);
                    if ($hookDTO->insert) {
                        $data = array_merge_recursive($entity->getObjVars(), $hookDTO->insert);
                        $dbInstance->table($tableName)->insert($data);
                    }
                    if ($hookDTO->update) {
                        $dbInstance->table($tableName)->where(['id' => $entity->getID()])->update($hookDTO->update);
                    }
                    if ($hookDTO->isDel) {
                        $dbInstance->table($tableName)->where(['id' => $entity->getID()])->delete();
                    }
                    self::removeEntityHookDTO($entity);
                }
                unset(self::$_entity[$k]);
            }
        } catch (\Exception $e) {
            DbContainer::rollBack();
            throw new LogicError($e->getMessage());
        }
        DbContainer::commitTrans();
    }

    private static function removeEntityHookDTO($cls)
    {
        $id      = $cls->getID();
        $clsName = get_class($cls);

        unset(self::$_entity[$clsName][$id]);
    }

}
